package lab

import (
	"bytes"
	"database/sql/driver"
	"encoding/json"
	"fmt"
	"net/http"
	"pdocker/config"
	"pdocker/docker"
	"strconv"
	"strings"
	"time"

	log "github.com/sirupsen/logrus"
)

func (t *Task) Create() error {
	for index, value := range t.Containers {
		id, err := docker.CreateLabContainer(value)
		if err != nil {
			return err
		}
		t.Containers[index].Id = id
	}
	return nil
}

func (t *Task) Start() {
	for index, value := range t.Containers {
		t.Containers[index].PortMapping = []string{"", ""}
		err := docker.StartContainer(value.Id)
		if err != nil {
			log.Error(err)
			return
		}
		container, _ := docker.GetContainerById(value.Id)
		t.Containers[index].PortMapping[0] = docker.GetContainerIP(container)
		if len(value.Ports) > 0 {
			p, _ := strconv.Atoi(strings.Split(value.Ports[0], "/")[0])
			port, _ := docker.GetPublicPort(uint16(p), container)
			t.Containers[index].PortMapping[1] = fmt.Sprintf("%s:%d", config.Config.Docker.Host, port)
		}
	}
	bytesData, _ := json.Marshal(t)
	_, _ = http.Post(t.Task.CallBack,
		"application/json;charset=utf-8", bytes.NewBuffer(bytesData))
	t.Init()
}

func (t *Task) Delete() {
	for _, value := range t.Containers {
		if value.Id != "" {
			_ = docker.DeleteContainer(value.Id, false)
		} else {
			log.Warningf("任务id: %s 容器id为空（数据错误，记录已删除）\n", t.Task.TaskId)
		}
	}
	log.Infof("任务id: %s 删除结束", t.Task.TaskId)
}

func (t *Task) Update(timeStamp int64) {
	log.Debugf("update task: %s timer %d", t.Task.TaskId, timeStamp)
	ok, timer := t.Timer(timeStamp)
	if ok {
		log.Debugf("更新任务: %s 成功", t.Task.TaskId)
		timerList[t.Task.TaskId] = timer
	} else {
		log.Debugf("更新任务: %s 失败 时间已经过期，尝试删除", t.Task.TaskId)
		t.Delete()
		table := TaskTable{Data: *t}
		table.Delete()
	}
}

func (t *Task) Init() {
	log.Debugf("update task: %s timer %d", t.Task.TaskId, t.Task.DestroyTimeStamp)
	ok, timer := t.Timer(t.Task.DestroyTimeStamp)
	if ok {
		log.Debugf("初始化任务: %s 成功", t.Task.TaskId)
		timerList[t.Task.TaskId] = timer
	} else {
		log.Warningf("初始化任务: %s 失败 时间已经过期，尝试删除", t.Task.TaskId)
		t.Delete()
		table := TaskTable{Data: *t}
		table.Delete()
	}
}

func (t *Task) Timer(timestamp int64) (bool, *time.Timer) {
	duration := time.Until(time.Unix(timestamp, 0))
	if duration < 0 {
		return false, nil
	}
	return true, time.AfterFunc(duration, func() {
		t.Delete()
	})
}

func (t *Task) Scan(val interface{}) (err error) {
	if bb, ok := val.([]byte); ok {
		err := json.Unmarshal(bb, &t)
		return err
	}
	return nil
}

func (t *Task) Copy() *Task {
	jsonData, _ := json.Marshal(t)
	copyTask := new(Task)
	_ = json.Unmarshal(jsonData, copyTask)
	return copyTask
}

func (t *Task) Value() (driver.Value, error) {
	response, _ := json.Marshal(t)
	return response, nil
}
